package com.imooc.mall.service.impl;

import com.imooc.mall.consts.MallConst;
import com.imooc.mall.dao.CategoryMapper;
import com.imooc.mall.pojo.Category;
import com.imooc.mall.service.CategoryService;
import com.imooc.mall.vo.CategoryVo;
import com.imooc.mall.vo.ResponseVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public void findSubCategoryId(Integer id, Set<Integer> set) {
        List<Category> categories = categoryMapper.selectAll();
        findSubCategoryId(categories, id, set);
    }

    private void findSubCategoryId(List<Category> categories, Integer id, Set<Integer> set) {
        for (Category category : categories) {
            if (category.getParentId().equals(id)) {
                set.add(category.getId());
                findSubCategoryId(categories, category.getId(), set);
            }
        }
    }


    /**
     * Created by 视频中的写法
     * 直接先一次性把数据把数据查到内存中
     * @return
     */
    @Override
    public ResponseVo<List<CategoryVo>> categories() {
        List<Category> categories = categoryMapper.selectAll();

        // 查询根目录
//        for (Category category : categories) {
//            if (category.getId().equals(MallConst.ROOT_PARENT_ID)) {
//                categoryVoList.add(copy(category));
//            }
//        }
        // stream流 + lambda表达式
        List<CategoryVo> categoryVoList = categories.stream()
                .filter(category -> category.getParentId().equals(MallConst.ROOT_PARENT_ID))
                .map(category -> copy(category))
                .collect(Collectors.toList());
        // 排序
        categoryVoList.sort(Comparator.comparing(CategoryVo::getSortOrder).reversed());

        // 查询子目录
        findSubCategory(categoryVoList, categories);

        return ResponseVo.success(categoryVoList);
    }

    private void findSubCategory(List<CategoryVo> categoryVoList, List<Category> categories) {
        for (CategoryVo categoryVo : categoryVoList) {
            ArrayList<CategoryVo> subCategories = new ArrayList<>();

            for (Category category : categories) {
                if (category.getParentId().equals(categoryVo.getId())) {
                    subCategories.add(copy(category));
                }
            }
            // 排序
            subCategories.sort(Comparator.comparing(CategoryVo::getSortOrder).reversed());
            categoryVo.setSubCategories(subCategories);

            findSubCategory(subCategories, categories);
        }
    }

    /**
     * 这样只能实现两级的目录。
     * 这种实现方式，无法动态调整目录的层数。
     * 感觉这样写好傻啊。
     * 这样一次一次的查询数据库，很慢。
     * 不如，一次性把数据读出来，然后在内存中再进行操作。
     * 分类表能有多少条数据？不会很大的。
     * @return
     */
//    @Override
//    public List<CategoryVo> categories() {
//        List<CategoryVo> categoryVoList = new ArrayList<>();
//
//        List<Category> categories = categoryMapper.queryAllParentCategories();
//        for (Category category : categories) {
//            categoryVoList.add(copy(category));
//        }
//
//        for (CategoryVo categoryVo : categoryVoList) {
//            categoryVo.setSubCategories(listCopy(categoryMapper.queryAllChildrenCategories(String.valueOf(categoryVo.getId()))));
//        }
//
//        for (CategoryVo categoryVo : categoryVoList) {
//            for (CategoryVo childrenCategoryVo : categoryVo.getSubCategories()) {
//                childrenCategoryVo.setSubCategories(listCopy(categoryMapper.queryAllChildrenCategories(String.valueOf(childrenCategoryVo.getId()))));
//            }
//        }
//
//        return categoryVoList;
//    }


    private CategoryVo copy(Category category) {
        CategoryVo categoryVo = new CategoryVo();
        BeanUtils.copyProperties(category, categoryVo);
        return categoryVo;
    }

    private List<CategoryVo> listCopy(List<Category> categoryList) {
        List<CategoryVo> categoryVoList = new ArrayList<>();
        for (Category category : categoryList) {
            categoryVoList.add(copy(category));
        }
        return categoryVoList;
    }

}
